package com.qisu.util;

/**
 * 字节阵列工具
 *
 * @author alsan
 *
 */
public final class ByteArrayUtils {
	/**
	 * 从阵列中读取Integer
	 *
	 * @param src 数据源
	 * @param from 数据读取起始位置
	 * @param bytes 读取数据字节数
	 * @param isBigEndian 是否高位在前
	 *
	 * @return Integer 读取的结果
	 */
	public static int getInteger(byte[] src, int from, int bytes, boolean isBigEndian) {
		int result = 0;

		for(int i = bytes; i > 0; i--) {
			int byteOrder = isBigEndian ? i - 1 : bytes - i;

			result |= ((src[i + from - 1]) & 0xff) << (byteOrder << 3);
		}

		return result;
	}

	/**
	 * 从阵列中读取Long
	 *
	 * @param src 数据源
	 * @param from 数据读取起始位置
	 * @param bytes 读取数据字节数
	 * @param isBigEndian 是否高位在前
	 *
	 * @return Long 读取的结果
	 */
	public static long getLong(byte[] src, int from, int bytes, boolean isBigEndian) {
		long result = 0;

		for(int i = bytes; i > 0; i--) {
			int byteOrder = isBigEndian ? i - 1 : bytes - i;

			result |= (((long)src[i + from - 1]) & 0xff) << (byteOrder << 3);
		}

		return result;
	}

	/**
	 * 转换二进数据为十六进字符串，每个字节中间插入空格，便于显示
	 *
	 * @param b 数据源
	 *
	 * @return String 十六进字符串
	 */
	public static String hexString(byte[] b) {
		StringBuffer d = new StringBuffer();

		for(byte c : b) {
			d.append(String.format("%02X", c));
		}

		return d.toString().trim();
	}

	/**
	 * 转换二进收据为BCD码
	 * 例如：0x20 0x17 0x06 0x11转成 20170611
	 *
	 * @param src 源数据
	 *
	 * @return String BCD结果
	 */
	public static String bytesToHexString(byte[] src) {
		if(src == null || src.length <= 0) {
			return null;
		}

		StringBuilder stringBuilder = new StringBuilder();

		for(byte b : src) {
			String hv = Integer.toHexString(b & 0xFF);

			stringBuilder.append(2 == hv.length() ? hv : "0" + hv);
		}

		return stringBuilder.toString();
	}

	/**
	 * BCD转换为byte[]，用于提交数据到第三方平台
	 * 例如： 20170611 转成 0x20 0x17 0x06 0x11
	 *
	 * @param hexString 源数据
	 *
	 * @return byte[] 转换结果
	 */
	public static byte[] hexStringToBytes(String hexString) {
		if(hexString == null || hexString.equals("")) {
			return null;
		}

		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];

		for(int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte)(charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	/**
	 * 字符转换为对应的二进字节
	 *
	 * @param c 源字符
	 *
	 * @return byte 转换结果
	 */
	public static byte charToByte(char c) {
		return (byte)"0123456789ABCDEF".indexOf(c);
	}

	/**
	 * 合并两个字节阵列
	 *
	 * @param byte1 第一段阵列
	 * @param byte2 第二段阵列
	 *
	 * @return byte[] 合并结果
	 */
	public static byte[] byteMerger(byte[] byte1, byte[] byte2) {
		byte[] merger = new byte[byte1.length + byte2.length];

		System.arraycopy(byte1, 0, merger, 0, byte1.length);
		System.arraycopy(byte2, 0, merger, byte1.length, byte2.length);

		return merger;
	}
}
